/** Copyright (C) 2012-2018 by Autodesk, Inc. All rights reserved. FANUC post processor configuration. $Revision: 42172 bd19858a62e243c722de6e4753876abf77ff3fb6 $ $Date: 2018-11-06 13:08:35 $ FORKID {04622D27-72F0-45d4-85FB-DB346FD1AE22} Modified for Syntec 60W-E With loading and unloading sequence by: Melchior Hof B.Sc. Technical Engineer melhof78@gmail.com PLEASE SHARE BACK ANY IMPROVEMENTS $Date: 2024-01-28 $ */ description = "Syntec 60W-E"; vendor = "GXU CNC"; vendorUrl = "http://www.fanuc.com"; legal = "Copyright (C) 2012-2018 by Autodesk, Inc."; certificationLevel = 2; minimumRevision = 40783; longDescription = "Modified post for Syntec 60W-E from Fanuc."; // added by Melchior extension = "nc"; programNameIsInteger = true; setCodePage("ascii"); capabilities = CAPABILITY_MILLING | CAPABILITY_MACHINE_SIMULATION; // capablity added by Melchior tolerance = spatial(0.002, MM); minimumChordLength = spatial(0.25, MM); minimumCircularRadius = spatial(0.01, MM); maximumCircularRadius = spatial(1000, MM); minimumCircularSweep = toRad(0.01); maximumCircularSweep = toRad(180); allowHelicalMoves = true; allowedCircularPlanes = undefined; // allow any circular motion // Start of machine configuration logic var compensateToolLength = false; // add the tool length to the pivot distance for nonTCP rotary heads var virtualTooltip = false; // translate the pivot point to the virtual tool tip for nonTCP rotary heads // internal variables, do not change var receivedMachineConfiguration; var tcpIsSupported; function activateMachine() { // determine if TCP is supported by the machine tcpIsSupported = false; var axes = [machineConfiguration.getAxisU(), machineConfiguration.getAxisV(), machineConfiguration.getAxisW()]; for (var i in axes) { if (axes[i].isEnabled() && axes[i].isTCPEnabled()) { tcpIsSupported = true; break; } } // setup usage of multiAxisFeatures useMultiAxisFeatures = getProperty("useMultiAxisFeatures") != undefined ? getProperty("useMultiAxisFeatures") : (typeof useMultiAxisFeatures != "undefined" ? useMultiAxisFeatures : false); useABCPrepositioning = getProperty("useABCPrepositioning") != undefined ? getProperty("useABCPrepositioning") : (typeof useABCPrepositioning != "undefined" ? useABCPrepositioning : false); if (!machineConfiguration.isMachineCoordinate(0) && (typeof aOutput != "undefined")) { aOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(1) && (typeof bOutput != "undefined")) { bOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(2) && (typeof cOutput != "undefined")) { cOutput.disable(); } if (!machineConfiguration.isMultiAxisConfiguration()) { return; // don't need to modify any settings for 3-axis machines } // retract/reconfigure safeRetractDistance = getProperty("safeRetractDistance") != undefined ? getProperty("safeRetractDistance") : (typeof safeRetractDistance == "number" ? safeRetractDistance : 0); if (machineConfiguration.performRewinds() || (typeof performRewinds == "undefined" ? false : performRewinds)) { machineConfiguration.enableMachineRewinds(); // enables the rewind/reconfigure logic if (typeof stockExpansion != "undefined") { machineConfiguration.setRewindStockExpansion(stockExpansion); if (!receivedMachineConfiguration) { setMachineConfiguration(machineConfiguration); } } } if (machineConfiguration.isHeadConfiguration()) { compensateToolLength = typeof compensateToolLength == "undefined" ? false : compensateToolLength; virtualTooltip = typeof virtualTooltip == "undefined" ? false : virtualTooltip; machineConfiguration.setVirtualTooltip(virtualTooltip); } setFeedrateMode(); if (machineConfiguration.isHeadConfiguration() && compensateToolLength) { for (var i = 0; i < getNumberOfSections(); ++i) { var section = getSection(i); if (section.isMultiAxis()) { machineConfiguration.setToolLength(getBodyLength(section.getTool())); // define the tool length for head adjustments section.optimizeMachineAnglesByMachine(machineConfiguration, tcpIsSupported ? 0 : 1); } } } else { optimizeMachineAngles2(tcpIsSupported ? 0 : 1); } } function setFeedrateMode(reset) { if ((tcpIsSupported && !reset) || !machineConfiguration.isMultiAxisConfiguration()) { return; } machineConfiguration.setMultiAxisFeedrate( tcpIsSupported ? FEED_FPM : FEED_INVERSE_TIME, 9999.99, // maximum output value for inverse time feed rates INVERSE_MINUTES, // can be INVERSE_SECONDS or DPM_COMBINATION for DPM feeds 0.5, // tolerance to determine when the DPM feed has changed 1.0 // ratio of rotary accuracy to linear accuracy for DPM calculations ); if (!receivedMachineConfiguration || (revision < 45765)) { setMachineConfiguration(machineConfiguration); } } function getBodyLength(tool) { for (var i = 0; i < getNumberOfSections(); ++i) { var section = getSection(i); if (tool.number == section.getTool().number) { return section.getParameter("operation:tool_overallLength", tool.bodyLength + tool.holderLength); } } return tool.bodyLength + tool.holderLength; } function defineMachine() { if (false) { // note: setup your machine here var aAxis = createAxis({coordinate:0, table:true, axis:[1, 0, 0], range:[-120, 120], preference:1, tcp:true}); var cAxis = createAxis({coordinate:2, table:true, axis:[0, 0, 1], range:[-360, 360], preference:0, tcp:true}); machineConfiguration = new MachineConfiguration(aAxis, cAxis); setMachineConfiguration(machineConfiguration); if (receivedMachineConfiguration) { warning(localize("The provided CAM machine configuration is overwritten by the postprocessor.")); receivedMachineConfiguration = false; // CAM provided machine configuration is overwritten } } /* home positions */ // machineConfiguration.setHomePositionX(toPreciseUnit(0, IN)); // machineConfiguration.setHomePositionY(toPreciseUnit(0, IN)); // machineConfiguration.setRetractPlane(toPreciseUnit(0, IN)); } // End of machine configuration logic // user-defined properties properties = { writeMachine: true, // write machine writeTools: true, // writes the tools preloadTool: false, // preloads next tool on tool change if any showSequenceNumbers: false, // show sequence numbers sequenceNumberStart: 10, // first sequence number sequenceNumberIncrement: 5, // increment for sequence numbers optionalStop: true, // optional stop o8: false, // specifies 8-digit program number separateWordsWithSpace: true, // specifies that the words should be separated with a white space autoLoadUnloadSequence: true, // specifies that the M405 loading unloading sequence gets performed before the program starts allow3DArcs: false, // specifies that 3D circular arcs are allowed useRadius: false, // specifies that arcs should be output using the radius (R word) instead of the I, J, and K words forceIJK: false, // force output of IJK for G2/G3 when not using R word useParametricFeed: false, // specifies that feed should be output using Q values showNotes: true, // specifies that operation notes should be output useSmoothing: false, // specifies if smoothing should be used or not usePitchForTapping: false, // enable to use pitch instead of feed for the F-word for canned tapping cycles - note that your CNC control must be setup for pitch mode! useG95: false, // use IPR/MPR instead of IPM/MPM useG28: false, // specifies that G28 should be used instead of G53 useG54x4: false, // Fanuc 30i supports G54.4 for Workpiece Error Compensation useSubroutines: false, // specifies that subroutines per each operation should be generated useSubroutinePatterns: false, // generates subroutines for patterned operation useSubroutineCycles: false, // generates subroutines for cycle operations on same holes useRigidTapping: "yes" // output rigid tapping block }; // user-defined property definitions propertyDefinitions = { writeMachine: {title:"Write machine", description:"Output the machine settings in the header of the code.", group:0, type:"boolean"}, writeTools: {title:"Write tool list", description:"Output a tool list in the header of the code.", group:0, type:"boolean"}, preloadTool: {title:"Preload tool", description:"Preloads the next tool at a tool change (if any).", group:1, type:"boolean"}, showSequenceNumbers: {title:"Use sequence numbers", description:"Use sequence numbers for each block of outputted code.", group:1, type:"boolean"}, sequenceNumberStart: {title:"Start sequence number", description:"The number at which to start the sequence numbers.", group:1, type:"integer"}, sequenceNumberIncrement: {title:"Sequence number increment", description:"The amount by which the sequence number is incremented by in each block.", group:1, type:"integer"}, optionalStop: {title:"Optional stop", description:"Outputs optional stop code during when necessary in the code.", type:"boolean"}, o8: {title:"8 Digit program number", description:"Specifies that an 8 digit program number is needed.", type:"boolean"}, separateWordsWithSpace: {title:"Separate words with space", description:"Adds spaces between words if 'yes' is selected.", type:"boolean"}, allow3DArcs: {title:"Allow 3D arcs", description:"Specifies whether 3D circular arcs are allowed.", type:"boolean"}, autoLoadUnloadSequence: {title:"M405 Load/Unload preprogram", description:"Activated loading/unloading sequence before program starts.", type:"boolean"}, useRadius: {title:"Radius arcs", description:"If yes is selected, arcs are outputted using radius values rather than IJK.", type:"boolean"}, forceIJK: {title:"Force IJK", description:"Force the output of IJK for G2/G3 when not using R mode.", type:"boolean"}, useParametricFeed: {title:"Parametric feed", description:"Specifies the feed value that should be output using a Q value.", type:"boolean"}, showNotes: {title:"Show notes", description:"Writes operation notes as comments in the outputted code.", type:"boolean"}, useSmoothing: {title:"Use smoothing", description:"Specifies if smoothing should be used or not.", type:"boolean"}, usePitchForTapping: {title:"Use pitch for tapping", description:"Enables the use of pitch instead of feed for the F-word in canned tapping cycles. Your CNC control must be setup for pitch mode!", type:"boolean"}, useG95: {title:"Use G95", description:"Use IPR/MPR instead of IPM/MPM.", type:"boolean"}, useG54x4: {title:"Use G54.4", description:"Fanuc 30i supports G54.4 for workpiece error compensation.", type:"boolean"}, useSubroutines: {title:"Use subroutines", description:"Specifies that subroutines per each operation should be generated.", type:"boolean"}, useSubroutinePatterns: {title:"Use subroutine patterns", description:"Generates subroutines for patterned operation.", type:"boolean"}, useSubroutineCycles: {title: "Use subroutine cycles", description: "Generates subroutines for cycle operations on same holes.", type: "boolean"}, useG28: {title: "G28 Safe retracts", description: "Disable to use G53 instead of G28 for retracts.", type: "boolean"}, useRigidTapping: { title: "Use rigid tapping", description: "Select 'Yes' to enable, 'No' to disable, or 'Without spindle direction' to enable rigid tapping without outputting the spindle direction block.", type: "enum", values:[ {title:"Yes", id:"yes"}, {title:"No", id:"no"}, {title:"Without spindle direction", id:"without"} ] } }; // samples: // throughTool: {on: 88, off: 89} // throughTool: {on: [8, 88], off: [9, 89]} var coolants = { flood: {on: 8}, mist: {}, throughTool: {on: 88, off: 89}, air: {}, airThroughTool: {}, suction: {}, floodMist: {}, floodThroughTool: {on: [8, 88], off: [9, 89]}, off: 9 }; var permittedCommentChars = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,=_-"; var gFormat = createFormat({prefix:"G", width:2, zeropad:true, decimals:1}); var mFormat = createFormat({prefix:"M", width:2, zeropad:true, decimals:1}); var hFormat = createFormat({prefix:"H", width:2, zeropad:true, decimals:1}); var dFormat = createFormat({prefix:"D", width:2, zeropad:true, decimals:1}); var probe100Format = createFormat({decimals:3, zeropad:true, width:3, forceDecimal:true}); var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); var ijkFormat = createFormat({decimals:6, forceDecimal:true}); // unitless var rFormat = xyzFormat; // radius var abcFormat = createFormat({decimals:3, forceDecimal:true, scale:DEG}); var feedFormat = createFormat({decimals:(unit == MM ? 0 : 1), forceDecimal:true}); var pitchFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); var toolFormat = createFormat({decimals:0}); var rpmFormat = createFormat({decimals:0}); var secFormat = createFormat({decimals:3, forceDecimal:true}); // seconds - range 0.001-99999.999 var milliFormat = createFormat({decimals:0}); // milliseconds // range 1-9999 var taperFormat = createFormat({decimals:1, scale:DEG}); var oFormat = createFormat({width:4, zeropad:true, decimals:0}); var xOutput = createVariable({prefix:"X"}, xyzFormat); var yOutput = createVariable({prefix:"Y"}, xyzFormat); var zOutput = createVariable({onchange: function() {retracted = false;}, prefix:"Z"}, xyzFormat); var aOutput = createVariable({prefix:"A"}, abcFormat); var bOutput = createVariable({prefix:"B"}, abcFormat); var cOutput = createVariable({prefix:"C"}, abcFormat); var feedOutput = createVariable({prefix:"F"}, feedFormat); var pitchOutput = createVariable({prefix:"F", force:true}, pitchFormat); var sOutput = createVariable({prefix:"S", force:true}, rpmFormat); var dOutput = createVariable({}, dFormat); // circular output var iOutput = createReferenceVariable({prefix:"I"}, xyzFormat); var jOutput = createReferenceVariable({prefix:"J"}, xyzFormat); var kOutput = createReferenceVariable({prefix:"K"}, xyzFormat); var gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... var gPlaneModal = createModal({onchange:function () {gMotionModal.reset();}}, gFormat); // modal group 2 // G17-19 var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 var gFeedModeModal = createModal({}, gFormat); // modal group 5 // G94-95 var gUnitModal = createModal({}, gFormat); // modal group 6 // G70-71 var gCycleModal = createModal({}, gFormat); // modal group 9 // G81, ... var gRetractModal = createModal({}, gFormat); // modal group 10 // G98-99 var gRotationModal = createModal({}, gFormat); // modal group 16 // G68-G69 // fixed settings var firstFeedParameter = 500; var useMultiAxisFeatures = false; var forceMultiAxisIndexing = false; // force multi-axis indexing for 3D programs var maximumLineLength = 80; // the maximum number of charaters allowed in a line var minimumCyclePoints = 5; // minimum number of points in cycle operation to consider for subprogram var cancelTiltFirst = false; // cancel G68.2 with G69 prior to G54-G59 WCS block var useABCPrepositioning = false; // position ABC axes prior to G68.2 block var WARNING_WORK_OFFSET = 0; var ANGLE_PROBE_NOT_SUPPORTED = 0; var ANGLE_PROBE_USE_ROTATION = 1; var ANGLE_PROBE_USE_CAXIS = 2; var SUB_UNKNOWN = 0; var SUB_PATTERN = 1; var SUB_CYCLE = 2; // collected state var sequenceNumber; var currentWorkOffset; var optionalSection = false; var forceSpindleSpeed = false; var activeMovements; // do not use by default var currentFeedId; var g68RotationMode = 0; var angularProbingMode; var subprograms = []; var currentPattern = -1; var firstPattern = false; var currentSubprogram; var lastSubprogram; var definedPatterns = new Array(); var incrementalMode = false; var saveShowSequenceNumbers; var cycleSubprogramIsActive = false; var patternIsActive = false; var lastOperationComment = ""; /** Writes the specified block. */ function writeBlock() { var text = formatWords(arguments); if (!text) { return; } if (properties.showSequenceNumbers) { if (optionalSection) { if (text) { writeWords("/", "N" + sequenceNumber, text); } } else { writeWords2("N" + sequenceNumber, arguments); } sequenceNumber += properties.sequenceNumberIncrement; } else { if (optionalSection) { writeWords2("/", arguments); } else { writeWords(arguments); } } } /** Writes the specified optional block. */ function writeOptionalBlock() { if (properties.showSequenceNumbers) { var words = formatWords(arguments); if (words) { writeWords("/", "N" + sequenceNumber, words); sequenceNumber += properties.sequenceNumberIncrement; } } else { writeWords2("/", arguments); } } function formatComment(text) { return "(" + filterText(String(text).toUpperCase(), permittedCommentChars).replace(/[()]/g, "") + ")"; } /** Output a comment. */ function writeComment(text) { writeln(formatComment(text)); } function onOpen() { //** Added by Melchior receivedMachineConfiguration = (typeof machineConfiguration.isReceived == "function") ? machineConfiguration.isReceived() : ((machineConfiguration.getDescription() != "") || machineConfiguration.isMultiAxisConfiguration()); if (typeof defineMachine == "function") { defineMachine(); // hardcoded machine configuration } activateMachine(); // enable the machine optimizations and settings // ** End of added by Melchior if (properties.useRadius) { maximumCircularSweep = toRad(90); // avoid potential center calculation errors for CNC } gRotationModal.format(69); // Default to G69 Rotation Off if (false) { // note: setup your machine here *Changed to false to disable kinematics from this area by Melchior* var aAxis = createAxis({coordinate:X, table:false, axis:[0, 1, 0], range:[-90, 90], preference:1}); machineConfiguration = new MachineConfiguration(aAxis); machineConfiguration.setVendor("GXU CNC"); machineConfiguration.setModel("MD-2500S"); machineConfiguration.setDescription("CNC ATC"); setMachineConfiguration(machineConfiguration); optimizeMachineAngles2(1); // TCP mode } if (!machineConfiguration.isMachineCoordinate(0)) { aOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(1)) { bOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(2)) { cOutput.disable(); } if (!properties.separateWordsWithSpace) { setWordSeparator(""); } if (properties.forceIJK) { iOutput = createReferenceVariable({prefix:"I", force:true}, xyzFormat); jOutput = createReferenceVariable({prefix:"J", force:true}, xyzFormat); kOutput = createReferenceVariable({prefix:"K", force:true}, xyzFormat); } sequenceNumber = properties.sequenceNumberStart; writeln("%"); if (programName) { var programId; try { programId = getAsInt(programName); } catch(e) { error(localize("Program name must be a number.")); return; } if (properties.o8) { if (!((programId >= 1) && (programId <= 99999999))) { error(localize("Program number is out of range.")); return; } } else { if (!((programId >= 1) && (programId <= 9999))) { error(localize("Program number is out of range.")); return; } } if ((programId >= 8000) && (programId <= 9999)) { warning(localize("Program number is reserved by tool builder.")); } oFormat = createFormat({width:(properties.o8 ? 8 : 4), zeropad:true, decimals:0}); if (programComment) { writeln("O" + oFormat.format(programId) + " (" + filterText(String(programComment).toUpperCase(), permittedCommentChars) + ")"); } else { writeln("O" + oFormat.format(programId)); } lastSubprogram = programId; } else { error(localize("Program name has not been specified.")); return; } // dump machine configuration var vendor = machineConfiguration.getVendor(); var model = machineConfiguration.getModel(); var description = machineConfiguration.getDescription(); if (properties.writeMachine && (vendor || model || description)) { writeComment(localize("Machine")); if (vendor) { writeComment(" " + localize("vendor") + ": " + vendor); } if (model) { writeComment(" " + localize("model") + ": " + model); } if (description) { writeComment(" " + localize("description") + ": " + description); } } // dump tool information if (properties.writeTools) { var zRanges = {}; if (is3D()) { var numberOfSections = getNumberOfSections(); for (var i = 0; i < numberOfSections; ++i) { var section = getSection(i); var zRange = section.getGlobalZRange(); var tool = section.getTool(); if (zRanges[tool.number]) { zRanges[tool.number].expandToRange(zRange); } else { zRanges[tool.number] = zRange; } } } var tools = getToolTable(); if (tools.getNumberOfTools() > 0) { for (var i = 0; i < tools.getNumberOfTools(); ++i) { var tool = tools.getTool(i); var comment = "T" + toolFormat.format(tool.number) + " " + "D=" + xyzFormat.format(tool.diameter) + " " + localize("CR") + "=" + xyzFormat.format(tool.cornerRadius); if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { comment += " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg"); } if (zRanges[tool.number]) { comment += " - " + localize("ZMIN") + "=" + xyzFormat.format(zRanges[tool.number].getMinimum()); } comment += " - " + getToolTypeName(tool.type); writeComment(comment); } } } if (false) { // check for duplicate tool number for (var i = 0; i < getNumberOfSections(); ++i) { var sectioni = getSection(i); var tooli = sectioni.getTool(); for (var j = i + 1; j < getNumberOfSections(); ++j) { var sectionj = getSection(j); var toolj = sectionj.getTool(); if (tooli.number == toolj.number) { if (xyzFormat.areDifferent(tooli.diameter, toolj.diameter) || xyzFormat.areDifferent(tooli.cornerRadius, toolj.cornerRadius) || abcFormat.areDifferent(tooli.taperAngle, toolj.taperAngle) || (tooli.numberOfFlutes != toolj.numberOfFlutes)) { error( subst( localize("Using the same tool number for different cutter geometry for operation '%1' and '%2'."), sectioni.hasParameter("operation-comment") ? sectioni.getParameter("operation-comment") : ("#" + (i + 1)), sectionj.hasParameter("operation-comment") ? sectionj.getParameter("operation-comment") : ("#" + (j + 1)) ) ); return; } } } } } if ((getNumberOfSections() > 0) && (getSection(0).workOffset == 0)) { for (var i = 0; i < getNumberOfSections(); ++i) { if (getSection(i).workOffset > 0) { error(localize("Using multiple work offsets is not possible if the initial work offset is 0.")); return; } } } //writeBlock(mFormat.format(00)); // Program stop user activation **added by Melchior if (properties.autoLoadUnloadSequence) { writeBlock(mFormat.format(405)); // Auto loading cycle optional **added by Melchior } // absolute coordinates and feed per min writeBlock(gAbsIncModal.format(90), gFeedModeModal.format(properties.useG95 ? 95 : 94), gPlaneModal.format(17), gFormat.format(49), gFormat.format(40), gFormat.format(80)); switch (unit) { case IN: writeBlock(gUnitModal.format(70)); break; case MM: writeBlock(gUnitModal.format(71)); break; } if (properties.useG95 && properties.useParametricFeed) { error(localize("Parametric feed is not supported when using G95.")); return; } if (properties.useG95) { feedFormat = createFormat({decimals:(unit == MM ? 4 : 5), forceDecimal:true}); feedOutput = createVariable({prefix:"F"}, feedFormat); } } function onComment(message) { var comments = String(message).split(";"); for (comment in comments) { writeComment(comments[comment]); } } /** Force output of X, Y, and Z. */ function forceXYZ() { xOutput.reset(); yOutput.reset(); zOutput.reset(); } /** Force output of A, B, and C. */ function forceABC() { aOutput.reset(); bOutput.reset(); cOutput.reset(); } function forceFeed() { currentFeedId = undefined; feedOutput.reset(); } /** Force output of X, Y, Z, A, B, C, and F on next output. */ function forceAny() { forceXYZ(); forceABC(); forceFeed(); } var lengthCompensationActive = false; var retracted = false; // specifies that the tool has been retracted to the safe plane /** Disables length compensation if currently active or if forced. */ function disableLengthCompensation(force) { if (lengthCompensationActive || force) { validate(retracted, "Cannot cancel length compensation if the machine is not fully retracted."); writeBlock(gFormat.format(49)); lengthCompensationActive = false; } } var currentSmoothing = false; function setSmoothing(mode) { if (mode == currentSmoothing) { return false; } // 1) Make sure G49 is called before the execution of G05.1 Q1 Rx // 2) G05.1 Q1 Rx must be engaged BEFORE G43-Tool Length Comp // 3) AICC and AIAPC need to be turned on and off for each tool // 4) AICC and AIAPC does not apply to canned drilling cycles validate(!lengthCompensationActive, "Length compensation is active while trying to update smoothing."); currentSmoothing = mode; writeBlock(gFormat.format(5.1), mode ? "Q1" : "Q0"); return true; } function FeedContext(id, description, feed) { this.id = id; this.description = description; this.feed = feed; } function getFeed(f) { if (properties.useG95) { return feedOutput.format(f/spindleSpeed); // use feed value } if (activeMovements) { var feedContext = activeMovements[movement]; if (feedContext != undefined) { if (!feedFormat.areDifferent(feedContext.feed, f)) { if (feedContext.id == currentFeedId) { return ""; // nothing has changed } forceFeed(); currentFeedId = feedContext.id; return "F#" + (firstFeedParameter + feedContext.id); } } currentFeedId = undefined; // force Q feed next time } return feedOutput.format(f); // use feed value } function initializeActiveFeeds() { activeMovements = new Array(); var movements = currentSection.getMovements(); var id = 0; var activeFeeds = new Array(); if (hasParameter("operation:tool_feedCutting")) { if (movements & ((1 << MOVEMENT_CUTTING) | (1 << MOVEMENT_LINK_TRANSITION) | (1 << MOVEMENT_EXTENDED))) { var feedContext = new FeedContext(id, localize("Cutting"), getParameter("operation:tool_feedCutting")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_CUTTING] = feedContext; activeMovements[MOVEMENT_LINK_TRANSITION] = feedContext; activeMovements[MOVEMENT_EXTENDED] = feedContext; } ++id; if (movements & (1 << MOVEMENT_PREDRILL)) { feedContext = new FeedContext(id, localize("Predrilling"), getParameter("operation:tool_feedCutting")); activeMovements[MOVEMENT_PREDRILL] = feedContext; activeFeeds.push(feedContext); } ++id; } if (hasParameter("operation:finishFeedrate")) { if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:finishFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; } ++id; } else if (hasParameter("operation:tool_feedCutting")) { if (movements & (1 << MOVEMENT_FINISH_CUTTING)) { var feedContext = new FeedContext(id, localize("Finish"), getParameter("operation:tool_feedCutting")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_FINISH_CUTTING] = feedContext; } ++id; } if (hasParameter("operation:tool_feedEntry")) { if (movements & (1 << MOVEMENT_LEAD_IN)) { var feedContext = new FeedContext(id, localize("Entry"), getParameter("operation:tool_feedEntry")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LEAD_IN] = feedContext; } ++id; } if (hasParameter("operation:tool_feedExit")) { if (movements & (1 << MOVEMENT_LEAD_OUT)) { var feedContext = new FeedContext(id, localize("Exit"), getParameter("operation:tool_feedExit")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LEAD_OUT] = feedContext; } ++id; } if (hasParameter("operation:noEngagementFeedrate")) { if (movements & (1 << MOVEMENT_LINK_DIRECT)) { var feedContext = new FeedContext(id, localize("Direct"), getParameter("operation:noEngagementFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; } ++id; } else if (hasParameter("operation:tool_feedCutting") && hasParameter("operation:tool_feedEntry") && hasParameter("operation:tool_feedExit")) { if (movements & (1 << MOVEMENT_LINK_DIRECT)) { var feedContext = new FeedContext(id, localize("Direct"), Math.max(getParameter("operation:tool_feedCutting"), getParameter("operation:tool_feedEntry"), getParameter("operation:tool_feedExit"))); activeFeeds.push(feedContext); activeMovements[MOVEMENT_LINK_DIRECT] = feedContext; } ++id; } if (hasParameter("operation:reducedFeedrate")) { if (movements & (1 << MOVEMENT_REDUCED)) { var feedContext = new FeedContext(id, localize("Reduced"), getParameter("operation:reducedFeedrate")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_REDUCED] = feedContext; } ++id; } if (hasParameter("operation:tool_feedRamp")) { if (movements & ((1 << MOVEMENT_RAMP) | (1 << MOVEMENT_RAMP_HELIX) | (1 << MOVEMENT_RAMP_PROFILE) | (1 << MOVEMENT_RAMP_ZIG_ZAG))) { var feedContext = new FeedContext(id, localize("Ramping"), getParameter("operation:tool_feedRamp")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_RAMP] = feedContext; activeMovements[MOVEMENT_RAMP_HELIX] = feedContext; activeMovements[MOVEMENT_RAMP_PROFILE] = feedContext; activeMovements[MOVEMENT_RAMP_ZIG_ZAG] = feedContext; } ++id; } if (hasParameter("operation:tool_feedPlunge")) { if (movements & (1 << MOVEMENT_PLUNGE)) { var feedContext = new FeedContext(id, localize("Plunge"), getParameter("operation:tool_feedPlunge")); activeFeeds.push(feedContext); activeMovements[MOVEMENT_PLUNGE] = feedContext; } ++id; } if (true) { // high feed if (movements & (1 << MOVEMENT_HIGH_FEED)) { var feedContext = new FeedContext(id, localize("High Feed"), this.highFeedrate); activeFeeds.push(feedContext); activeMovements[MOVEMENT_HIGH_FEED] = feedContext; } ++id; } for (var i = 0; i < activeFeeds.length; ++i) { var feedContext = activeFeeds[i]; writeBlock("#" + (firstFeedParameter + feedContext.id) + "=" + feedFormat.format(feedContext.feed), formatComment(feedContext.description)); } } var currentWorkPlaneABC = undefined; function forceWorkPlane() { currentWorkPlaneABC = undefined; } function defineWorkPlane(_section, _setWorkPlane) { var abc = new Vector(0, 0, 0); if (forceMultiAxisIndexing || !is3D() || machineConfiguration.isMultiAxisConfiguration()) { // use 5-axis indexing for multi-axis mode // set working plane after datum shift if (_section.isMultiAxis()) { cancelTransformation(); if (_setWorkPlane) { forceWorkPlane(); } if (machineConfiguration.isMultiAxisConfiguration()) { abc = _section.getInitialToolAxisABC(); if (_setWorkPlane) { if (!retracted) { writeRetract(Z); } onCommand(COMMAND_UNLOCK_MULTI_AXIS); gMotionModal.reset(); writeBlock( gMotionModal.format(0), conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)), conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)), conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z)) ); } } else { var d = currentSection.getGlobalInitialToolAxis(); // position writeBlock( gAbsIncModal.format(90), gMotionModal.format(0), "I" + xyzFormat.format(d.x), "J" + xyzFormat.format(d.y), "K" + xyzFormat.format(d.z) ); } } else { if (useMultiAxisFeatures) { var euler = _section.workPlane.getEuler2(EULER_ZXZ_R); abc = new Vector(euler.x, euler.y, euler.z); cancelTransformation(); } else { abc = getWorkPlaneMachineABC(_section.workPlane, _setWorkPlane, true); } if (_setWorkPlane) { setWorkPlane(abc); } } } else { // pure 3D var remaining = _section.workPlane; if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { error(localize("Tool orientation is not supported.")); return abc; } setRotation(remaining); } return abc; } function cancelWorkPlane() { writeBlock(gRotationModal.format(69)); // cancel frame forceWorkPlane(); } function setWorkPlane(abc) { if (!forceMultiAxisIndexing && is3D() && !machineConfiguration.isMultiAxisConfiguration()) { return; // ignore } if (!((currentWorkPlaneABC == undefined) || abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) || abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) || abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z))) { return; // no change } onCommand(COMMAND_UNLOCK_MULTI_AXIS); if (!retracted) { writeRetract(Z); } if (useMultiAxisFeatures) { if (cancelTiltFirst) { cancelWorkPlane(); } if (machineConfiguration.isMultiAxisConfiguration() && useABCPrepositioning) { var angles = abc.isNonZero() ? getWorkPlaneMachineABC(currentSection.workPlane, false) : abc; gMotionModal.reset(); writeBlock( gMotionModal.format(0), conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(angles.x)), conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(angles.y)), conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(angles.z)) ); } if (abc.isNonZero()) { gRotationModal.reset(); /* // Modified Code writeBlock(gFormat.format(18)); writeBlock(gRotationModal.format(68), "Y" + xyzFormat.format(0), "Z" + xyzFormat.format(0), "R" + abcFormat.format(abc.x)); // set frame writeBlock(gFormat.format(53)); // turn machine */ // Original Code writeBlock(gRotationModal.format(68.2), "X" + xyzFormat.format(0), "Y" + xyzFormat.format(0), "Z" + xyzFormat.format(0), "A" + abcFormat.format(abc.x), "B" + abcFormat.format(abc.y), "C" + abcFormat.format(abc.z)); // set frame writeBlock(gFormat.format(53.1)); // turn machine } else { if (!cancelTiltFirst) { cancelWorkPlane(); } } } else { gMotionModal.reset(); writeBlock( gMotionModal.format(0), conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)), conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)), conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z)) ); } onCommand(COMMAND_LOCK_MULTI_AXIS); currentWorkPlaneABC = abc; setCurrentABC(abc); //**Added by Melchior } var closestABC = false; // choose closest machine angles var currentMachineABC; function getWorkPlaneMachineABC(workPlane, _setWorkPlane, rotate) { var W = workPlane; // map to global frame var abc = machineConfiguration.getABC(W); if (closestABC) { if (currentMachineABC) { abc = machineConfiguration.remapToABC(abc, currentMachineABC); } else { abc = machineConfiguration.getPreferredABC(abc); } } else { abc = machineConfiguration.getPreferredABC(abc); } try { abc = machineConfiguration.remapABC(abc); if (_setWorkPlane) { currentMachineABC = abc; } } catch (e) { error( localize("Machine angles not supported") + ":" + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) ); } var direction = machineConfiguration.getDirection(abc); if (!isSameDirection(direction, W.forward)) { error(localize("Orientation not supported.")); } if (!machineConfiguration.isABCSupported(abc)) { error( localize("Work plane is not supported") + ":" + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) ); } if (rotate) { var tcp = true; // important set this to true ... otherwise ... the movements of the Z axis are not changed by those of the X if (tcp) { setRotation(W); // TCP mode } else { var O = machineConfiguration.getOrientation(abc); var R = machineConfiguration.getRemainingOrientation(abc, W); setRotation(R); } } return abc; } function isProbeOperation() { return hasParameter("operation-strategy") && (getParameter("operation-strategy") == "probe"); } var probeOutputWorkOffset = 1; function onParameter(name, value) { if (name == "probe-output-work-offset") { probeOutputWorkOffset = (value > 0) ? value : 1; } } /** Returns true if the spatial vectors are significantly different. */ function areSpatialVectorsDifferent(_vector1, _vector2) { return (xyzFormat.getResultingValue(_vector1.x) != xyzFormat.getResultingValue(_vector2.x)) || (xyzFormat.getResultingValue(_vector1.y) != xyzFormat.getResultingValue(_vector2.y)) || (xyzFormat.getResultingValue(_vector1.z) != xyzFormat.getResultingValue(_vector2.z)); } /** Returns true if the spatial boxes are a pure translation. */ function areSpatialBoxesTranslated(_box1, _box2) { return !areSpatialVectorsDifferent(Vector.diff(_box1[1], _box1[0]), Vector.diff(_box2[1], _box2[0])) && !areSpatialVectorsDifferent(Vector.diff(_box2[0], _box1[0]), Vector.diff(_box2[1], _box1[1])); } function subprogramDefine(_initialPosition, _abc, _retracted, _zIsOutput) { // convert patterns into subprograms var usePattern = false; patternIsActive = false; if (currentSection.isPatterned && currentSection.isPatterned() && properties.useSubroutinePatterns) { currentPattern = currentSection.getPatternId(); firstPattern = true; for (var i = 0; i < definedPatterns.length; ++i) { if ((definedPatterns[i].patternType == SUB_PATTERN) && (currentPattern == definedPatterns[i].patternId)) { currentSubprogram = definedPatterns[i].subProgram; usePattern = definedPatterns[i].validPattern; firstPattern = false; break; } } if (firstPattern) { // determine if this is a valid pattern for creating a subprogram usePattern = subprogramIsValid(currentSection, currentPattern, SUB_PATTERN); if (usePattern) { currentSubprogram = ++lastSubprogram; } definedPatterns.push({ patternType: SUB_PATTERN, patternId: currentPattern, subProgram: currentSubprogram, validPattern: usePattern, initialPosition: _initialPosition, finalPosition: _initialPosition }); } if (usePattern) { // make sure Z-position is output prior to subprogram call if (!_retracted && !_zIsOutput) { writeBlock(gMotionModal.format(0), zOutput.format(_initialPosition.z)); } // call subprogram writeBlock(mFormat.format(98), "P" + oFormat.format(currentSubprogram)); patternIsActive = true; if (firstPattern) { subprogramStart(_initialPosition, _abc, true); } else { skipRemainingSection(); setCurrentPosition(getFramePosition(currentSection.getFinalPosition())); } } } // Output cycle operation as subprogram if (!usePattern && properties.useSubroutineCycles && currentSection.doesStrictCycle && (currentSection.getNumberOfCycles() == 1) && currentSection.getNumberOfCyclePoints() >= minimumCyclePoints) { var finalPosition = getFramePosition(currentSection.getFinalPosition()); currentPattern = currentSection.getNumberOfCyclePoints(); firstPattern = true; for (var i = 0; i < definedPatterns.length; ++i) { if ((definedPatterns[i].patternType == SUB_CYCLE) && (currentPattern == definedPatterns[i].patternId) && !areSpatialVectorsDifferent(_initialPosition, definedPatterns[i].initialPosition) && !areSpatialVectorsDifferent(finalPosition, definedPatterns[i].finalPosition)) { currentSubprogram = definedPatterns[i].subProgram; usePattern = definedPatterns[i].validPattern; firstPattern = false; break; } } if (firstPattern) { // determine if this is a valid pattern for creating a subprogram usePattern = subprogramIsValid(currentSection, currentPattern, SUB_CYCLE); if (usePattern) { currentSubprogram = ++lastSubprogram; } definedPatterns.push({ patternType: SUB_CYCLE, patternId: currentPattern, subProgram: currentSubprogram, validPattern: usePattern, initialPosition: _initialPosition, finalPosition: finalPosition }); } cycleSubprogramIsActive = usePattern; } // Output each operation as a subprogram if (!usePattern && properties.useSubroutines) { currentSubprogram = ++lastSubprogram; writeBlock(mFormat.format(98), "P" + oFormat.format(currentSubprogram)); firstPattern = true; subprogramStart(_initialPosition, _abc, false); } } function subprogramStart(_initialPosition, _abc, _incremental) { redirectToBuffer(); var comment = ""; if (hasParameter("operation-comment")) { comment = getParameter("operation-comment"); } writeln( "O" + oFormat.format(currentSubprogram) + conditional(comment, formatComment(comment.substr(0, maximumLineLength - 2 - 6 - 1))) ); saveShowSequenceNumbers = properties.showSequenceNumbers; properties.showSequenceNumbers = false; if (_incremental) { setIncrementalMode(_initialPosition, _abc); } gPlaneModal.reset(); gMotionModal.reset(); } function subprogramEnd() { if (firstPattern) { writeBlock(mFormat.format(99)); writeln(""); subprograms += getRedirectionBuffer(); } forceAny(); firstPattern = false; properties.showSequenceNumbers = saveShowSequenceNumbers; closeRedirection(); } function subprogramIsValid(_section, _patternId, _patternType) { var sectionId = _section.getId(); var numberOfSections = getNumberOfSections(); var validSubprogram = _patternType != SUB_CYCLE; var masterPosition = new Array(); masterPosition[0] = getFramePosition(_section.getInitialPosition()); masterPosition[1] = getFramePosition(_section.getFinalPosition()); var tempBox = _section.getBoundingBox(); var masterBox = new Array(); masterBox[0] = getFramePosition(tempBox[0]); masterBox[1] = getFramePosition(tempBox[1]); var rotation = getRotation(); var translation = getTranslation(); for (var i = 0; i < numberOfSections; ++i) { var section = getSection(i); if (section.getId() != sectionId) { defineWorkPlane(section, false); // check for valid pattern if (_patternType == SUB_PATTERN) { if (section.getPatternId() == _patternId) { var patternPosition = new Array(); patternPosition[0] = getFramePosition(section.getInitialPosition()); patternPosition[1] = getFramePosition(section.getFinalPosition()); tempBox = section.getBoundingBox(); var patternBox = new Array(); patternBox[0] = getFramePosition(tempBox[0]); patternBox[1] = getFramePosition(tempBox[1]); if (!areSpatialBoxesTranslated(masterPosition, patternPosition) || !areSpatialBoxesTranslated(masterBox, patternBox)) { validSubprogram = false; break; } } // check for valid cycle operation } else if (_patternType == SUB_CYCLE) { if ((section.getNumberOfCyclePoints() == _patternId) && (section.getNumberOfCycles() == 1)) { var patternInitial = getFramePosition(section.getInitialPosition()); var patternFinal = getFramePosition(section.getFinalPosition()); if (!areSpatialVectorsDifferent(patternInitial, masterPosition[0]) && !areSpatialVectorsDifferent(patternFinal, masterPosition[1])) { validSubprogram = true; break; } } } } } setRotation(rotation); setTranslation(translation); return(validSubprogram); } function setAxisMode(_format, _output, _prefix, _value, _incr) { var i = _output.isEnabled(); _output = _incr ? createIncrementalVariable({prefix: _prefix}, _format) : createVariable({prefix: _prefix}, _format); _output.format(_value); _output.format(_value); i = i ? _output.enable() : _output.disable(); return _output; } function setIncrementalMode(xyz, abc) { xOutput = setAxisMode(xyzFormat, xOutput, "X", xyz.x, true); yOutput = setAxisMode(xyzFormat, yOutput, "Y", xyz.y, true); zOutput = setAxisMode(xyzFormat, zOutput, "Z", xyz.z, true); aOutput = setAxisMode(abcFormat, aOutput, "A", abc.x, true); bOutput = setAxisMode(abcFormat, bOutput, "B", abc.y, true); cOutput = setAxisMode(abcFormat, cOutput, "C", abc.z, true); gAbsIncModal.reset(); writeBlock(gAbsIncModal.format(91)); incrementalMode = true; } function setAbsoluteMode(xyz, abc) { if (incrementalMode) { xOutput = setAxisMode(xyzFormat, xOutput, "X", xyz.x, false); yOutput = setAxisMode(xyzFormat, yOutput, "Y", xyz.y, false); zOutput = setAxisMode(xyzFormat, zOutput, "Z", xyz.z, false); aOutput = setAxisMode(abcFormat, aOutput, "A", abc.x, false); bOutput = setAxisMode(abcFormat, bOutput, "B", abc.y, false); cOutput = setAxisMode(abcFormat, cOutput, "C", abc.z, false); gAbsIncModal.reset(); writeBlock(gAbsIncModal.format(90)); incrementalMode = false; } } function onSection() { var forceToolAndRetract = optionalSection && !currentSection.isOptional(); optionalSection = currentSection.isOptional(); var insertToolCall = forceToolAndRetract || isFirstSection() || currentSection.getForceToolChange && currentSection.getForceToolChange() || (tool.number != getPreviousSection().getTool().number); var zIsOutput = false; // true if the Z-position has been output, used for patterns var newWorkOffset = isFirstSection() || (getPreviousSection().workOffset != currentSection.workOffset); // work offset changes var newWorkPlane = isFirstSection() || !isSameDirection(getPreviousSection().getGlobalFinalToolAxis(), currentSection.getGlobalInitialToolAxis()) || (currentSection.isOptimizedForMachine() && getPreviousSection().isOptimizedForMachine() && Vector.diff(getPreviousSection().getFinalToolAxisABC(), currentSection.getInitialToolAxisABC()).length > 1e-4) || (!machineConfiguration.isMultiAxisConfiguration() && currentSection.isMultiAxis()) || (!getPreviousSection().isMultiAxis() && currentSection.isMultiAxis()); // force newWorkPlane between indexing and simultaneous operations var forceSmoothing = properties.useSmoothing && (hasParameter("operation-strategy") && (getParameter("operation-strategy") == "drill") || !isFirstSection() && getPreviousSection().hasParameter("operation-strategy") && (getPreviousSection().getParameter("operation-strategy") == "drill")); // force smoothing in case !insertToolCall (2d chamfer) if (insertToolCall || newWorkOffset || newWorkPlane || forceSmoothing) { // stop spindle before retract during tool change if (insertToolCall && !isFirstSection()) { onCommand(COMMAND_STOP_SPINDLE); } // retract to safe plane writeRetract(Z); // retract forceXYZ(); if ((insertToolCall && !isFirstSection()) || forceSmoothing) { disableLengthCompensation(); setSmoothing(false); } } if (hasParameter("operation-comment")) { var comment = getParameter("operation-comment"); if (comment && ((comment !== lastOperationComment) || !patternIsActive || insertToolCall)) { writeln(""); writeComment(comment); lastOperationComment = comment; } else if (!patternIsActive || insertToolCall) { writeln(""); } } else { writeln(""); } if (properties.showNotes && hasParameter("notes")) { var notes = getParameter("notes"); if (notes) { var lines = String(notes).split("\n"); var r1 = new RegExp("^[\\s]+", "g"); var r2 = new RegExp("[\\s]+$", "g"); for (line in lines) { var comment = lines[line].replace(r1, "").replace(r2, ""); if (comment) { writeComment(comment); } } } } if (insertToolCall) { forceWorkPlane(); onCommand(COMMAND_COOLANT_OFF); if (!isFirstSection() && properties.optionalStop) { onCommand(COMMAND_OPTIONAL_STOP); } if (tool.number > 99) { warning(localize("Tool number exceeds maximum value.")); } disableLengthCompensation(); writeBlock("T" + toolFormat.format(tool.number), mFormat.format(6)); if (tool.comment) { writeComment(tool.comment); } var showToolZMin = false; if (showToolZMin) { if (is3D()) { var numberOfSections = getNumberOfSections(); var zRange = currentSection.getGlobalZRange(); var number = tool.number; for (var i = currentSection.getId() + 1; i < numberOfSections; ++i) { var section = getSection(i); if (section.getTool().number != number) { break; } zRange.expandToRange(section.getGlobalZRange()); } writeComment(localize("ZMIN") + "=" + zRange.getMinimum()); } } if (properties.preloadTool) { var nextTool = getNextTool(tool.number); if (nextTool) { writeBlock("T" + toolFormat.format(nextTool.number)); } else { // preload first tool var section = getSection(0); var firstToolNumber = section.getTool().number; if (tool.number != firstToolNumber) { writeBlock("T" + toolFormat.format(firstToolNumber)); } } } } if (!isProbeOperation() && (insertToolCall || forceSpindleSpeed || isFirstSection() || (rpmFormat.areDifferent(spindleSpeed, sOutput.getCurrent())) || (tool.clockwise != getPreviousSection().getTool().clockwise))) { forceSpindleSpeed = false; if (spindleSpeed < 1) { error(localize("Spindle speed out of range.")); return; } if (spindleSpeed > 99999) { warning(localize("Spindle speed exceeds maximum value.")); } var tapping = hasParameter("operation:cycleType") && ((getParameter("operation:cycleType") == "tapping") || (getParameter("operation:cycleType") == "right-tapping") || (getParameter("operation:cycleType") == "left-tapping") || (getParameter("operation:cycleType") == "tapping-with-chip-breaking")); if (!tapping || (tapping && !(properties.useRigidTapping == "without"))) { writeBlock( sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4) ); } onCommand(COMMAND_START_CHIP_TRANSPORT); if (forceMultiAxisIndexing || !is3D() || machineConfiguration.isMultiAxisConfiguration()) { // writeBlock(mFormat.format(xxx)); // shortest path traverse } } // wcs if (insertToolCall) { // force work offset when changing tool currentWorkOffset = undefined; } var workOffset = currentSection.workOffset; if (workOffset == 0) { warningOnce(localize("Work offset has not been specified. Using G54 as WCS."), WARNING_WORK_OFFSET); workOffset = 1; } if (workOffset != currentWorkOffset) { if (cancelTiltFirst) { cancelWorkPlane(); } forceWorkPlane(); } if (workOffset > 0) { if (workOffset > 6) { var p = workOffset - 6; // 1->... if (p > 300) { error(localize("Work offset out of range.")); return; } else { if (workOffset != currentWorkOffset) { writeBlock(gFormat.format(54.1), "P" + p); // G54.1P currentWorkOffset = workOffset; } } } else { if (workOffset != currentWorkOffset) { writeBlock(gFormat.format(53 + workOffset)); // G54->G59 currentWorkOffset = workOffset; } } } forceXYZ(); var abc = defineWorkPlane(currentSection, true); // set coolant after we have positioned at Z setCoolant(tool.coolant); if (properties.useSmoothing) { if (hasParameter("operation-strategy") && (getParameter("operation-strategy") != "drill")) { if (setSmoothing(true)) { // we force G43 using lengthCompensationActive } } else { if (setSmoothing(false)) { // we force G43 using lengthCompensationActive } } } forceAny(); gMotionModal.reset(); var initialPosition = getFramePosition(currentSection.getInitialPosition()); if (!retracted && !insertToolCall) { if (getCurrentPosition().z < initialPosition.z) { writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z)); zIsOutput = true; } } if (insertToolCall || !lengthCompensationActive || retracted || (!isFirstSection() && getPreviousSection().isMultiAxis())) { var lengthOffset = tool.lengthOffset; if (lengthOffset > 99) { error(localize("Length offset out of range.")); return; } gMotionModal.reset(); writeBlock(gPlaneModal.format(17)); /* // cancel compensation prior to enabling it, required when switching G43/G43.4 modes disableLengthCompensation(false); // assumes a Head configuration uses TCP on a Fanuc controller var offsetCode = 43; if (currentSection.isMultiAxis()) { if (machineConfiguration.isMultiAxisConfiguration() && (currentSection.getOptimizedTCPMode() == 0)) { offsetCode = 43.4; } else if (!machineConfiguration.isMultiAxisConfiguration()) { offsetCode = 43.5; } } */ var offsetCode = 43; if (!machineConfiguration.isHeadConfiguration()) { writeBlock( gAbsIncModal.format(90), gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y) ); writeBlock( gMotionModal.format(0), gFormat.format(offsetCode), zOutput.format(initialPosition.z), hFormat.format(lengthOffset) ); lengthCompensationActive = true; } else { writeBlock( gAbsIncModal.format(90), gMotionModal.format(0), gFormat.format(offsetCode), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y), zOutput.format(initialPosition.z), hFormat.format(lengthOffset) ); lengthCompensationActive = true; } zIsOutput = true; gMotionModal.reset(); } else { writeBlock( gAbsIncModal.format(90), gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y) ); } validate(lengthCompensationActive, "Length compensation is not active."); if (properties.useParametricFeed && hasParameter("operation-strategy") && (getParameter("operation-strategy") != "drill") && // legacy !(currentSection.hasAnyCycle && currentSection.hasAnyCycle())) { if (!insertToolCall && activeMovements && (getCurrentSectionId() > 0) && ((getPreviousSection().getPatternId() == currentSection.getPatternId()) && (currentSection.getPatternId() != 0))) { // use the current feeds } else { initializeActiveFeeds(); } } else { activeMovements = undefined; } if (isProbeOperation()) { if (g68RotationMode != 0) { error(localize("You cannot probe while G68 Rotation is in effect.")); return; } angularProbingMode = getAngularProbingMode(); writeBlock(gFormat.format(65), "P" + 9832); // spin the probe on } // define subprogram subprogramDefine(initialPosition, abc, retracted, zIsOutput); retracted = false; } function onDwell(seconds) { if (seconds > 99999.999) { warning(localize("Dwelling time is out of range.")); } milliseconds = clamp(1, seconds * 1000, 99999999); writeBlock(gFeedModeModal.format(94), gFormat.format(4), "P" + milliFormat.format(milliseconds)); writeBlock(gFeedModeModal.format(properties.useG95 ? 95 : 94)); // back to G95 } function onSpindleSpeed(spindleSpeed) { writeBlock(sOutput.format(spindleSpeed)); } function onCycle() { writeBlock(gPlaneModal.format(17)); } function getCommonCycle(x, y, z, r, c) { forceXYZ(); // force xyz on first drill hole of any cycle if (incrementalMode) { zOutput.format(c); return [xOutput.format(x), yOutput.format(y), "Z" + xyzFormat.format(z - r), "R" + xyzFormat.format(r - c)]; } else { return [xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + xyzFormat.format(r)]; } } function setCyclePosition(_position) { switch (gPlaneModal.getCurrent()) { case 17: // XY zOutput.format(_position); break; case 18: // ZX yOutput.format(_position); break; case 19: // YZ xOutput.format(_position); break; } } /** Convert approach to sign. */ function approach(value) { validate((value == "positive") || (value == "negative"), "Invalid approach."); return (value == "positive") ? 1 : -1; } /** Determine if angular probing is supported */ function getAngularProbingMode() { if (machineConfiguration.isMultiAxisConfiguration()) { if (machineConfiguration.isMachineCoordinate(2)) { return ANGLE_PROBE_USE_CAXIS; } else { return ANGLE_PROBE_NOT_SUPPORTED; } } else { return ANGLE_PROBE_USE_ROTATION; } } /** Output rotation offset based on angular probing cycle. */ function setProbingAngle() { if ((g68RotationMode == 1) || (g68RotationMode == 2)) { // Rotate coordinate system for Angle Probing if (!properties.useG54x4) { gRotationModal.reset(); gAbsIncModal.reset(); writeBlock( gRotationModal.format(68), gAbsIncModal.format(90), (g68RotationMode == 1) ? "X0" : "X[#135]", (g68RotationMode == 1) ? "Y0" : "Y[#136]", "Z0", "I0.0", "J0.0", "K1.0", "R[#139]" ); g68RotationMode = 3; } else if (angularProbingMode != ANGLE_PROBE_NOT_SUPPORTED) { writeBlock("#26010=#135"); writeBlock("#26011=#136"); writeBlock("#26012=#137"); writeBlock("#26015=#139"); writeBlock(gFormat.format(54.4), "P1"); g68RotationMode = 0; } else { error(localize("Angular probing is not supported for this machine configuration.")); return; } } } function onCyclePoint(x, y, z) { if (!isSameDirection(getRotation().forward, new Vector(0, 0, 1))) { expandCyclePoint(x, y, z); return; } var probeWorkOffsetCode; if (isProbeOperation()) { if (!useMultiAxisFeatures && !isSameDirection(currentSection.workPlane.forward, new Vector(0, 0, 1)) && (!cycle.probeMode || (cycle.probeMode == 0))) { error(localize("Updating WCS / work offset using probing is only supported by the CNC in the WCS frame.")); return; } var workOffset = probeOutputWorkOffset ? probeOutputWorkOffset : currentWorkOffset; if (workOffset > 99) { error(localize("Work offset is out of range.")); return; } else if (workOffset > 6) { probeWorkOffsetCode = probe100Format.format(workOffset - 6 + 100); } else { probeWorkOffsetCode = workOffset + "."; // G54->G59 } } if (isFirstCyclePoint()) { repositionToCycleClearance(cycle, x, y, z); // return to initial Z which is clearance plane and set absolute mode var F = cycle.feedrate; if (properties.useG95) { F /= spindleSpeed; } var P = !cycle.dwell ? 0 : clamp(1, cycle.dwell * 1000, 99999999); // in milliseconds var forceCycle = false; switch (cycleType) { case "drilling": writeBlock( gRetractModal.format(98), gCycleModal.format(81), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), feedOutput.format(F) ); break; case "counter-boring": if (P > 0) { writeBlock( gRetractModal.format(98), gCycleModal.format(82), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), feedOutput.format(F) ); } else { writeBlock( gRetractModal.format(98), gCycleModal.format(81), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), feedOutput.format(F) ); } break; case "chip-breaking": // cycle.accumulatedDepth is ignored if (P > 0) { expandCyclePoint(x, y, z); } else { writeBlock( gRetractModal.format(98), gCycleModal.format(73), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "Q" + xyzFormat.format(cycle.incrementalDepth), feedOutput.format(F) ); } break; case "deep-drilling": if (P > 0) { expandCyclePoint(x, y, z); } else { writeBlock( gRetractModal.format(98), gCycleModal.format(83), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "Q" + xyzFormat.format(cycle.incrementalDepth), // conditional(P > 0, "P" + milliFormat.format(P)), feedOutput.format(F) ); } break; case "tapping": if (properties.useRigidTapping != "no") { writeBlock(mFormat.format(29), sOutput.format(spindleSpeed)); } if (properties.usePitchForTapping) { writeBlock( gRetractModal.format(98), gFeedModeModal.format(95), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND) ? 74 : 84), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), pitchOutput.format(tool.threadPitch) ); forceFeed(); } else { var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); F = (properties.useG95 ? tool.getThreadPitch() : tappingFPM); writeBlock( gRetractModal.format(98), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND) ? 74 : 84), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), feedOutput.format(F) ); } break; case "left-tapping": if (properties.useRigidTapping != "no") { writeBlock(mFormat.format(29), sOutput.format(spindleSpeed)); } if (properties.usePitchForTapping) { writeBlock( gRetractModal.format(98), gFeedModeModal.format(95), gCycleModal.format(74), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), pitchOutput.format(tool.threadPitch) ); forceFeed(); } else { var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); F = (properties.useG95 ? tool.getThreadPitch() : tappingFPM); writeBlock( gRetractModal.format(98), gCycleModal.format(74), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), feedOutput.format(F) ); } break; case "right-tapping": if (properties.useRigidTapping != "no") { writeBlock(mFormat.format(29), sOutput.format(spindleSpeed)); } if (properties.usePitchForTapping) { writeBlock( gRetractModal.format(98), gFeedModeModal.format(95), gCycleModal.format(84), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), pitchOutput.format(tool.threadPitch) ); forceFeed(); } else { var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); F = (properties.useG95 ? tool.getThreadPitch() : tappingFPM); writeBlock( gRetractModal.format(98), gCycleModal.format(84), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), feedOutput.format(F) ); } break; case "tapping-with-chip-breaking": case "left-tapping-with-chip-breaking": case "right-tapping-with-chip-breaking": if (properties.useRigidTapping != "no") { writeBlock(mFormat.format(29), sOutput.format(spindleSpeed)); } if (properties.usePitchForTapping) { writeBlock( gRetractModal.format(98), gFeedModeModal.format(95), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND ? 74 : 84)), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), "Q" + xyzFormat.format(cycle.incrementalDepth), pitchOutput.format(tool.threadPitch) ); forceFeed(); } else { var tappingFPM = tool.getThreadPitch() * rpmFormat.getResultingValue(spindleSpeed); F = (properties.useG95 ? tool.getThreadPitch() : tappingFPM); writeBlock( gRetractModal.format(98), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND ? 74 : 84)), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), "Q" + xyzFormat.format(cycle.incrementalDepth), feedOutput.format(F) ); } break; case "fine-boring": writeBlock( gRetractModal.format(98), gCycleModal.format(76), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), // not optional "Q" + xyzFormat.format(cycle.shift), feedOutput.format(F) ); break; case "back-boring": var dx = (gPlaneModal.getCurrent() == 19) ? cycle.backBoreDistance : 0; var dy = (gPlaneModal.getCurrent() == 18) ? cycle.backBoreDistance : 0; var dz = (gPlaneModal.getCurrent() == 17) ? cycle.backBoreDistance : 0; writeBlock( gRetractModal.format(98), gCycleModal.format(87), getCommonCycle(x - dx, y - dy, z - dz, cycle.bottom, cycle.clearance), "Q" + xyzFormat.format(cycle.shift), "P" + milliFormat.format(P), // not optional feedOutput.format(F) ); break; case "reaming": if (P > 0) { writeBlock( gRetractModal.format(98), gCycleModal.format(89), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), feedOutput.format(F) ); } else { writeBlock( gRetractModal.format(98), gCycleModal.format(85), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), feedOutput.format(F) ); } break; case "stop-boring": if (P > 0) { expandCyclePoint(x, y, z); } else { writeBlock( gRetractModal.format(98), gCycleModal.format(86), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), feedOutput.format(F) ); } break; case "manual-boring": writeBlock( gRetractModal.format(98), gCycleModal.format(88), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), // not optional feedOutput.format(F) ); break; case "boring": if (P > 0) { writeBlock( gRetractModal.format(98), gCycleModal.format(89), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), "P" + milliFormat.format(P), // not optional feedOutput.format(F) ); } else { writeBlock( gRetractModal.format(98), gCycleModal.format(85), getCommonCycle(x, y, z, cycle.retract, cycle.clearance), feedOutput.format(F) ); } break; case "probing-x": forceXYZ(); // move slowly always from clearance not retract writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9811, "X" + xyzFormat.format(x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter/2)), "Q" + xyzFormat.format(cycle.probeOvertravel), "S" + probeWorkOffsetCode // "T" + toolFormat.format(probeToolDiameterOffset) ); break; case "probing-y": forceXYZ(); writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9811, "Y" + xyzFormat.format(y + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter/2)), "Q" + xyzFormat.format(cycle.probeOvertravel), "S" + probeWorkOffsetCode // "T" + toolFormat.format(probeToolDiameterOffset) ); break; case "probing-z": forceXYZ(); writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(Math.min(z - cycle.depth + cycle.probeClearance, cycle.retract)), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9811, "Z" + xyzFormat.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "S" + probeWorkOffsetCode // "T" + toolFormat.format(probeToolLengthOffset) ); break; case "probing-x-wall": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "X" + xyzFormat.format(cycle.width1), zOutput.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(cycle.probeClearance), "S" + probeWorkOffsetCode // "T" + toolFormat.format(probeToolDiameterOffset) ); break; case "probing-y-wall": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "Y" + xyzFormat.format(cycle.width1), zOutput.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(cycle.probeClearance), "S" + probeWorkOffsetCode // "T" + toolFormat.format(probeToolDiameterOffset) ); break; case "probing-x-channel": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "X" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(cycle.probeClearance), "S" + probeWorkOffsetCode // "T" + toolFormat.format(probeToolDiameterOffset) ); break; case "probing-x-channel-with-island": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "X" + xyzFormat.format(cycle.width1), zOutput.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), "S" + probeWorkOffsetCode ); break; case "probing-y-channel": yOutput.reset(); writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "Y" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(cycle.probeClearance), "S" + probeWorkOffsetCode ); break; case "probing-y-channel-with-island": yOutput.reset(); writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "Y" + xyzFormat.format(cycle.width1), zOutput.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), "S" + probeWorkOffsetCode ); break; case "probing-xy-circular-boss": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9814, "D" + xyzFormat.format(cycle.width1), "Z" + xyzFormat.format(z - cycle.depth), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(cycle.probeClearance), "S" + probeWorkOffsetCode ); break; case "probing-xy-circular-hole": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9814, "D" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(cycle.probeClearance), "S" + probeWorkOffsetCode ); break; case "probing-xy-circular-hole-with-island": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9814, "Z" + xyzFormat.format(z - cycle.depth), "D" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), "S" + probeWorkOffsetCode ); break; case "probing-xy-rectangular-hole": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "X" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(-cycle.probeClearance), "S" + probeWorkOffsetCode ); writeBlock( gFormat.format(65), "P" + 9812, "Y" + xyzFormat.format(cycle.width2), "Q" + xyzFormat.format(cycle.probeOvertravel), // not required "R" + xyzFormat.format(-cycle.probeClearance), "S" + probeWorkOffsetCode ); break; case "probing-xy-rectangular-boss": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "Z" + xyzFormat.format(z - cycle.depth), "X" + xyzFormat.format(cycle.width1), "R" + xyzFormat.format(cycle.probeClearance), "Q" + xyzFormat.format(cycle.probeOvertravel), "S" + probeWorkOffsetCode ); writeBlock( gFormat.format(65), "P" + 9812, "Z" + xyzFormat.format(z - cycle.depth), "Y" + xyzFormat.format(cycle.width2), "R" + xyzFormat.format(cycle.probeClearance), "Q" + xyzFormat.format(cycle.probeOvertravel), "S" + probeWorkOffsetCode ); break; case "probing-xy-rectangular-hole-with-island": writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9812, "Z" + xyzFormat.format(z - cycle.depth), "X" + xyzFormat.format(cycle.width1), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), "S" + probeWorkOffsetCode ); writeBlock( gFormat.format(65), "P" + 9812, "Z" + xyzFormat.format(z - cycle.depth), "Y" + xyzFormat.format(cycle.width2), "Q" + xyzFormat.format(cycle.probeOvertravel), "R" + xyzFormat.format(-cycle.probeClearance), "S" + probeWorkOffsetCode ); break; case "probing-xy-inner-corner": var cornerX = x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter/2); var cornerY = y + approach(cycle.approach2) * (cycle.probeClearance + tool.diameter/2); var cornerI = 0; var cornerJ = 0; if (cycle.probeSpacing !== undefined) { cornerI = cycle.probeSpacing; cornerJ = cycle.probeSpacing; } if ((cornerI != 0) && (cornerJ != 0)) { g68RotationMode = 2; } writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9815, xOutput.format(cornerX), yOutput.format(cornerY), conditional(cornerI != 0, "I" + xyzFormat.format(cornerI)), conditional(cornerJ != 0, "J" + xyzFormat.format(cornerJ)), "Q" + xyzFormat.format(cycle.probeOvertravel), conditional((g68RotationMode == 0) || (angularProbingMode == ANGLE_PROBE_USE_CAXIS), "S" + probeWorkOffsetCode) ); break; case "probing-xy-outer-corner": var cornerX = x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter/2); var cornerY = y + approach(cycle.approach2) * (cycle.probeClearance + tool.diameter/2); var cornerI = 0; var cornerJ = 0; if (cycle.probeSpacing !== undefined) { cornerI = cycle.probeSpacing; cornerJ = cycle.probeSpacing; } if ((cornerI != 0) && (cornerJ != 0)) { g68RotationMode = 2; } writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9816, xOutput.format(cornerX), yOutput.format(cornerY), conditional(cornerI != 0, "I" + xyzFormat.format(cornerI)), conditional(cornerJ != 0, "J" + xyzFormat.format(cornerJ)), "Q" + xyzFormat.format(cycle.probeOvertravel), conditional((g68RotationMode == 0) || (angularProbingMode == ANGLE_PROBE_USE_CAXIS), "S" + probeWorkOffsetCode) ); break; case "probing-x-plane-angle": forceXYZ(); writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9843, "X" + xyzFormat.format(x + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter/2)), "D" + xyzFormat.format(cycle.probeSpacing), "Q" + xyzFormat.format(cycle.probeOvertravel) ); g68RotationMode = 1; break; case "probing-y-plane-angle": forceXYZ(); writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(z - cycle.depth), getFeed(F)); // protected positioning move writeBlock( gFormat.format(65), "P" + 9843, "Y" + xyzFormat.format(y + approach(cycle.approach1) * (cycle.probeClearance + tool.diameter/2)), "D" + xyzFormat.format(cycle.probeSpacing), "Q" + xyzFormat.format(cycle.probeOvertravel) ); g68RotationMode = 1; break; default: expandCyclePoint(x, y, z); } // place cycle operation in subprogram if (cycleSubprogramIsActive) { if (forceCycle || cycleExpanded || isProbeOperation()) { cycleSubprogramIsActive = false; } else { // call subprogram writeBlock(mFormat.format(98), "P" + oFormat.format(currentSubprogram)); subprogramStart(new Vector(x, y, z), new Vector(0, 0, 0), false); } } if (incrementalMode) { // set current position to clearance height setCyclePosition(cycle.clearance); } // 2nd through nth cycle point } else { if (isProbeOperation()) { // do nothing } else if (cycleExpanded) { expandCyclePoint(x, y, z); } else { if (!xyzFormat.areDifferent(x, xOutput.getCurrent()) && !xyzFormat.areDifferent(y, yOutput.getCurrent()) && !xyzFormat.areDifferent(z, zOutput.getCurrent())) { switch (gPlaneModal.getCurrent()) { case 17: // XY xOutput.reset(); // at least one axis is required break; case 18: // ZX zOutput.reset(); // at least one axis is required break; case 19: // YZ yOutput.reset(); // at least one axis is required break; } } if (incrementalMode) { // set current position to retract height setCyclePosition(cycle.retract); } writeBlock(xOutput.format(x), yOutput.format(y), zOutput.format(z)); if (incrementalMode) { // set current position to clearance height setCyclePosition(cycle.clearance); } } } } function onCycleEnd() { if (isProbeOperation()) { writeBlock(gFormat.format(65), "P" + 9810, zOutput.format(cycle.clearance)); // protected retract move writeBlock(gFormat.format(65), "P" + 9833); // spin the probe off setProbingAngle(); // define rotation of part // we can move in rapid from retract optionally } else { if (cycleSubprogramIsActive) { subprogramEnd(); cycleSubprogramIsActive = false; } if (!cycleExpanded) { writeBlock(conditional(!properties.useG95, gFeedModeModal.format(94)), gCycleModal.format(80)); zOutput.reset(); } } } var pendingRadiusCompensation = -1; function onRadiusCompensation() { pendingRadiusCompensation = radiusCompensation; } function onRapid(_x, _y, _z) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); if (x || y || z) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation mode cannot be changed at rapid traversal.")); return; } writeBlock(gMotionModal.format(0), x, y, z); forceFeed(); } } function onLinear(_x, _y, _z, feed) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var f = getFeed(feed); if (x || y || z) { if (pendingRadiusCompensation >= 0) { pendingRadiusCompensation = -1; var d = tool.diameterOffset; if (d > 99) { warning(localize("The diameter offset exceeds the maximum value.")); } writeBlock(gPlaneModal.format(17)); switch (radiusCompensation) { case RADIUS_COMPENSATION_LEFT: dOutput.reset(); writeBlock(gMotionModal.format(1), gFormat.format(41), x, y, z, dOutput.format(d), f); break; case RADIUS_COMPENSATION_RIGHT: dOutput.reset(); writeBlock(gMotionModal.format(1), gFormat.format(42), x, y, z, dOutput.format(d), f); break; default: writeBlock(gMotionModal.format(1), gFormat.format(40), x, y, z, f); } } else { writeBlock(gMotionModal.format(1), x, y, z, f); } } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion forceFeed(); // force feed on next line } else { writeBlock(gMotionModal.format(1), f); } } } function onRapid5D(_x, _y, _z, _a, _b, _c) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation mode cannot be changed at rapid traversal.")); return; } if (currentSection.isOptimizedForMachine()) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var a = aOutput.format(_a); var b = bOutput.format(_b); var c = cOutput.format(_c); writeBlock(gMotionModal.format(0), x, y, z, a, b, c); } else { forceXYZ(); var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var i = ijkFormat.format(_a); var j = ijkFormat.format(_b); var k = ijkFormat.format(_c); writeBlock(gMotionModal.format(0), x, y, z, "I" + i, "J" + j, "K" + k); } forceFeed(); } function onLinear5D(_x, _y, _z, _a, _b, _c, feed) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for 5-axis move.")); return; } if (currentSection.isOptimizedForMachine()) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var a = aOutput.format(_a); var b = bOutput.format(_b); var c = cOutput.format(_c); var f = getFeed(feed); if (x || y || z || a || b || c) { writeBlock(gMotionModal.format(1), x, y, z, a, b, c, f); } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion forceFeed(); // force feed on next line } else { writeBlock(gMotionModal.format(1), f); } } } else { forceXYZ(); var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var i = ijkFormat.format(_a); var j = ijkFormat.format(_b); var k = ijkFormat.format(_c); var f = getFeed(feed); if (x || y || z || i || j || k) { writeBlock(gMotionModal.format(1), x, y, z, "I" + i, "J" + j, "K" + k, f); } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion forceFeed(); // force feed on next line } else { writeBlock(gMotionModal.format(1), f); } } } } function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); return; } var start = getCurrentPosition(); if (isFullCircle()) { if (properties.useRadius || isHelical()) { // radius mode does not support full arcs linearize(tolerance); return; } switch (getCircularPlane()) { case PLANE_XY: writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); break; case PLANE_ZX: writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); break; case PLANE_YZ: writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); break; default: linearize(tolerance); } } else if (!properties.useRadius) { switch (getCircularPlane()) { case PLANE_XY: writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), getFeed(feed)); break; case PLANE_ZX: writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); break; case PLANE_YZ: writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), getFeed(feed)); break; default: if (properties.allow3DArcs) { // make sure maximumCircularSweep is well below 360deg // we could use G02.4 or G03.4 - direction is calculated var ip = getPositionU(0.5); writeBlock(gMotionModal.format(clockwise ? 2.4 : 3.4), xOutput.format(ip.x), yOutput.format(ip.y), zOutput.format(ip.z), getFeed(feed)); writeBlock(xOutput.format(x), yOutput.format(y), zOutput.format(z)); } else { linearize(tolerance); } } } else { // use radius mode var r = getCircularRadius(); if (toDeg(getCircularSweep()) > (180 + 1e-9)) { r = -r; // allow up to <360 deg arcs } switch (getCircularPlane()) { case PLANE_XY: writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); break; case PLANE_ZX: writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); break; case PLANE_YZ: writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), getFeed(feed)); break; default: if (properties.allow3DArcs) { // make sure maximumCircularSweep is well below 360deg // we could use G02.4 or G03.4 - direction is calculated var ip = getPositionU(0.5); writeBlock(gMotionModal.format(clockwise ? 2.4 : 3.4), xOutput.format(ip.x), yOutput.format(ip.y), zOutput.format(ip.z), getFeed(feed)); writeBlock(xOutput.format(x), yOutput.format(y), zOutput.format(z)); } else { linearize(tolerance); } } } } var currentCoolantMode = COOLANT_OFF; var coolantOff = undefined; function setCoolant(coolant) { var coolantCodes = getCoolantCodes(coolant); if (Array.isArray(coolantCodes)) { for (var c in coolantCodes) { writeBlock(coolantCodes[c]); } return undefined; } return coolantCodes; } function getCoolantCodes(coolant) { if (!coolants) { error(localize("Coolants have not been defined.")); } if (!coolantOff) { // use the default coolant off command when an 'off' value is not specified for the previous coolant mode coolantOff = coolants.off; } if (isProbeOperation()) { // avoid coolant output for probing coolant = COOLANT_OFF; } if (coolant == currentCoolantMode) { return undefined; // coolant is already active } var multipleCoolantBlocks = new Array(); // create a formatted array to be passed into the outputted line if ((coolant != COOLANT_OFF) && (currentCoolantMode != COOLANT_OFF)) { multipleCoolantBlocks.push(mFormat.format(coolantOff)); } var m; if (coolant == COOLANT_OFF) { m = coolantOff; coolantOff = coolants.off; } switch (coolant) { case COOLANT_FLOOD: if (!coolants.flood) { break; } m = coolants.flood.on; coolantOff = coolants.flood.off; break; case COOLANT_THROUGH_TOOL: if (!coolants.throughTool) { break; } m = coolants.throughTool.on; coolantOff = coolants.throughTool.off; break; case COOLANT_AIR: if (!coolants.air) { break; } m = coolants.air.on; coolantOff = coolants.air.off; break; case COOLANT_AIR_THROUGH_TOOL: if (!coolants.airThroughTool) { break; } m = coolants.airThroughTool.on; coolantOff = coolants.airThroughTool.off; break; case COOLANT_FLOOD_MIST: if (!coolants.floodMist) { break; } m = coolants.floodMist.on; coolantOff = coolants.floodMist.off; break; case COOLANT_MIST: if (!coolants.mist) { break; } m = coolants.mist.on; coolantOff = coolants.mist.off; break; case COOLANT_SUCTION: if (!coolants.suction) { break; } m = coolants.suction.on; coolantOff = coolants.suction.off; break; case COOLANT_FLOOD_THROUGH_TOOL: if (!coolants.floodThroughTool) { break; } m = coolants.floodThroughTool.on; coolantOff = coolants.floodThroughTool.off; break; } if (!m) { onUnsupportedCoolant(coolant); m = 9; } if (m) { if (Array.isArray(m)) { for (var i in m) { multipleCoolantBlocks.push(mFormat.format(m[i])); } } else { multipleCoolantBlocks.push(mFormat.format(m)); } currentCoolantMode = coolant; return multipleCoolantBlocks; // return the single formatted coolant value } return undefined; } var mapCommand = { COMMAND_STOP:0, COMMAND_OPTIONAL_STOP:1, COMMAND_END:2, COMMAND_SPINDLE_CLOCKWISE:3, COMMAND_SPINDLE_COUNTERCLOCKWISE:4, COMMAND_STOP_SPINDLE:5, COMMAND_ORIENTATE_SPINDLE:19 }; function onCommand(command) { switch (command) { case COMMAND_COOLANT_OFF: setCoolant(COOLANT_OFF); return; case COMMAND_COOLANT_ON: setCoolant(COOLANT_FLOOD); return; case COMMAND_STOP: writeBlock(mFormat.format(0)); forceSpindleSpeed = true; return; case COMMAND_START_SPINDLE: onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); return; case COMMAND_LOCK_MULTI_AXIS: return; case COMMAND_UNLOCK_MULTI_AXIS: return; case COMMAND_START_CHIP_TRANSPORT: return; case COMMAND_STOP_CHIP_TRANSPORT: return; case COMMAND_BREAK_CONTROL: return; case COMMAND_TOOL_MEASURE: return; } var stringId = getCommandStringId(command); var mcode = mapCommand[stringId]; if (mcode != undefined) { writeBlock(mFormat.format(mcode)); } else { onUnsupportedCommand(command); } } function onSectionEnd() { writeBlock(gPlaneModal.format(17)); if (((getCurrentSectionId() + 1) >= getNumberOfSections()) || (tool.number != getNextSection().getTool().number)) { onCommand(COMMAND_BREAK_CONTROL); } if (!isLastSection() && (getNextSection().getTool().coolant != tool.coolant)) { setCoolant(COOLANT_OFF); } if (true) { if (isRedirecting()) { if (firstPattern) { var finalPosition = getFramePosition(currentSection.getFinalPosition()); var abc; if (currentSection.isMultiAxis() && machineConfiguration.isMultiAxisConfiguration()) { abc = currentSection.getFinalToolAxisABC(); } else { abc = currentWorkPlaneABC; } if (abc == undefined) { abc = new Vector(0, 0, 0); } setAbsoluteMode(finalPosition, abc); subprogramEnd(); } } } forceAny(); } /** Output block to do safe retract and/or move to home position. */ function writeRetract() { // initialize routine var _xyzMoved = new Array(false, false, false); var _useG28 = properties.useG28; // can be either true or false // check syntax of call if (arguments.length == 0) { error(localize("No axis specified for writeRetract().")); return; } for (var i = 0; i < arguments.length; ++i) { if ((arguments[i] < 0) || (arguments[i] > 2)) { error(localize("Bad axis specified for writeRetract().")); return; } if (_xyzMoved[arguments[i]]) { error(localize("Cannot retract the same axis twice in one line")); return; } _xyzMoved[arguments[i]] = true; } // special conditions // define home positions var _xHome; var _yHome; var _zHome; if (_useG28) { _xHome = 0; _yHome = 0; _zHome = 0; } else { _xHome = machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : 0; _yHome = machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : 0; _zHome = machineConfiguration.getRetractPlane(); } // format home positions var words = []; // store all retracted axes in an array for (var i = 0; i < arguments.length; ++i) { // define the axes to move switch (arguments[i]) { case X: if (!machineConfiguration.hasHomePositionX()) { _useG28 = true; } words.push("X" + xyzFormat.format(_xHome)); break; case Y: if (!machineConfiguration.hasHomePositionY()) { _useG28 = true; } words.push("Y" + xyzFormat.format(_yHome)); break; case Z: words.push("Z" + xyzFormat.format(_zHome)); retracted = true; break; } } // output move to home if (words.length > 0) { if (_useG28) { gAbsIncModal.reset(); writeBlock(gFormat.format(28), gAbsIncModal.format(91), words); writeBlock(gAbsIncModal.format(90)); } else { gMotionModal.reset(); writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words); } // force any axes that move to home on next block if (_xyzMoved[0]) { xOutput.reset(); } if (_xyzMoved[1]) { yOutput.reset(); } if (_xyzMoved[2]) { zOutput.reset(); } } } function onClose() { writeln(""); optionalSection = false; onCommand(COMMAND_COOLANT_OFF); writeRetract(Z); // retract disableLengthCompensation(true); setSmoothing(false); zOutput.reset(); setWorkPlane(new Vector(0, 0, 0)); // reset working plane if (properties.useG54x4) { writeBlock(gFormat.format(54.4), "P0"); } writeRetract(X, Y); // return to home onImpliedCommand(COMMAND_END); onImpliedCommand(COMMAND_STOP_SPINDLE); writeBlock(mFormat.format(5)); // stop spindle *added by Melchior writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off if (subprograms.length > 0) { writeln(""); write(subprograms); } writeln("%"); }